package com.cal.utms.model.payment;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.cal.utms.action.user_maintenance.LoginAction;
import com.cal.utms.dao.maintenance.CustomerDaoImpl;
import com.cal.utms.dao.maintenance.IssuerDaoImpl;
import com.cal.utms.dao.maintenance.NewFundDao;
import com.cal.utms.dao.maintenance.SystemConfigurationDaoImpl;
import com.cal.utms.dao.payment.ReceiptDaoImpl;
import com.cal.utms.dto.payment.BankAccountDto;
import com.cal.utms.dto.payment.ReceiptDto;
import com.cal.utms.entity.Customer;
import com.cal.utms.entity.Fund;
import com.cal.utms.entity.Issuer;
import com.cal.utms.entity.MoneyTransaction;
import com.cal.utms.entity.Receipt;
import com.cal.utms.util.Sequence;

public class ReceiptModel {

	ReceiptDaoImpl daoImpl = new ReceiptDaoImpl();
	CustomerDaoImpl customerDaoImpl = new CustomerDaoImpl();
	IssuerDaoImpl issuerDaoImpl = new IssuerDaoImpl();
	NewFundDao fundDao = new NewFundDao();
	SystemConfigurationDaoImpl configurationDaoImpl = new SystemConfigurationDaoImpl();
	SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);
	CommenPayementModel commenPayementModel = new CommenPayementModel();

	public List<ReceiptDto> getReceipt() {
		List<ReceiptDto> receiptDtos = new ArrayList<ReceiptDto>();
		List<Receipt> list = daoImpl.getReceipts();
		for (Receipt receipt : list) {
			ReceiptDto dto = new ReceiptDto();
			dto.setAmount(receipt.getAmount().toString());
			dto.setBankId(receipt.getBankId());
			dto.setBankAccount(receipt.getBankAccount());
			dto.setBankName(receipt.getBankName());
			if (receipt.getPaymentType().equals("C")) {
				dto.setChequeBank(receipt.getChequeBank());
				if (receipt.getChequeDate() != null)
					dto.setChequeDate(format.format(receipt.getChequeDate()));
			} else {
				dto.setBankName(receipt.getBankName());
			}

			dto.setChequeNo(receipt.getChequeNo());
			dto.setConfUserId(receipt.getConfUserId());
			dto.setCustomerType(receipt.getCustomerType());
			dto.setCustomerId(receipt.getCustomerId());
			if (receipt.getCustomerType().equals("CUS")) {
				Customer customer = customerDaoImpl.getCustomerById(receipt.getCustomerId());
				dto.setCustomerCode(customer.getCode());
				if (customer.getAccountType().equals("C"))
					dto.setCustomerName(customer.getSurname());
				else
					dto.setCustomerName(customer.getDenotedByInitials().concat(" " + customer.getSurname()));
			} else if (receipt.getCustomerType().equals("ISU")) {
				Issuer issuer = issuerDaoImpl.getById(receipt.getCustomerId());
				dto.setCustomerCode(issuer.getCode());
				dto.setCustomerName(issuer.getName());
			}
			if (receipt.getDepositAccount() != null) {
				Fund fund = receipt.getFund();
				if (receipt.getDepositAccount().equals("N")) {
					dto.setFundid(fund.getId());
					dto.setFundAccount(configurationDaoImpl.getValueByPropName("accountNo"));
					dto.setFundBank(configurationDaoImpl.getValueByPropName("nameOfBank"));
					dto.setFundName(fund.getFundCode().concat(" - " + fund.getFundName()));
				} else {
					dto.setFundid(fund.getId());
					dto.setFundAccount(fund.getCdsAccount());
					dto.setFundBank(fund.getCustodian().getName());
					dto.setFundName(fund.getFundCode().concat(" - " + fund.getFundName()));
				}
			}

			dto.setId(receipt.getId());
			dto.setInstruction(receipt.getInstruction());
			dto.setPaymentType(receipt.getPaymentType());
			dto.setPurpose(receipt.getPurpose());
			dto.setReceiptNo(receipt.getReceiptNo());
			// dto.setReqDate(receipt.getReqDate());
			dto.setReqUserId(receipt.getReqUserId());
			dto.setStatus(receipt.getStatus());

			receiptDtos.add(dto);
		}
		return receiptDtos;
	}

	public void confirmReceipt(int receiptid, ReceiptDto receiptDto) {

		Receipt receipt = daoImpl.getReceiptById(receiptid);
		if (receipt != null && receiptDto != null) {
			receipt.setStatus((byte) 1);
			receipt.setConfDate(new Date());
			receipt.setPurpose(receiptDto.getPurpose());
			receipt.setConfUserId(LoginAction.getCurrentLogingUser().getId());
			if (receipt.getPaymentType().equals("C")) {
				receipt.setInstruction(receiptDto.getInstruction());
				receipt.setChequeBank(receiptDto.getChequeBank());
				try {
					receipt.setChequeDate(format.parse(receiptDto.getChequeDate()));
				} catch (ParseException e) {
					e.printStackTrace();
				}
				receipt.setChequeNo(receiptDto.getChequeNo());
			} else {
				BankAccountDto accountDto = commenPayementModel.getBankAccount(receipt.getCustomerId(), receipt.getCustomerType(), receiptDto.getBankId());
				if (accountDto != null) {
					receipt.setBankAccount(accountDto.getAccountNo());
					receipt.setBankName(accountDto.getNameOfBank());
					receipt.setBankId(receiptDto.getBankId());
				}
			}
		}
		MoneyTransactionModel model = new MoneyTransactionModel();

		List<MoneyTransaction> moneyTransactions = model.getReceiptTransaction(receiptDto, receipt);

		daoImpl.confirmPayment(receipt, moneyTransactions);
		receiptDto.setSuccess(true);
		receiptDto.setResulteMsg("SUCCESS");

	}

	public void saveReceipt(String receiptRequests, int fundId, ReceiptDto receiptDto) {
		if (receiptRequests != null) {
			Sequence seq = new Sequence();
			receiptRequests = "{ \"receiptRequests\" : ".concat(receiptRequests) + " }";
			List<Receipt> receipts = new ArrayList<Receipt>();
			try {
				JSONObject jsonObject = new JSONObject(receiptRequests);
				JSONArray jArray = jsonObject.getJSONArray("receiptRequests");
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject jObj = jArray.getJSONObject(i);
					Receipt receipt = new Receipt();
					receipt.setAmount(BigDecimal.valueOf(jObj.getDouble("amount")));
					receipt.setCustomerId(jObj.getInt("customerId"));
					receipt.setCustomerType(jObj.getString("customerType"));
					receipt.setPaymentType(jObj.getString("paymentType"));
					receipt.setReceiptNo("REC" + seq.getNextValue("RECEIPT"));
					receipt.setFund(fundDao.getById(fundId));
					receipt.setReqDate(new Date());
					receipt.setDepositAccount("C");
					receipt.setReqUserId(LoginAction.getCurrentLogingUser().getId());
					receipts.add(receipt);
				}

				Object object = daoImpl.saveReceipt(receipts);
				if (object instanceof Integer) {
					receiptDto.setId((Integer) object);
					receiptDto.setSuccess(true);
					receiptDto.setResulteMsg("SUCCESS");
				} else {
					receiptDto.setSuccess(false);
					receiptDto.setResulteMsg("There is some error returned from the server.");
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

	public List<ReceiptDto> getConfirmReceipt() {
		List<ReceiptDto> receiptDtos = new ArrayList<ReceiptDto>();
		List<Receipt> list = daoImpl.getConfirmReceipts();
		for (Receipt receipt : list) {
			ReceiptDto dto = new ReceiptDto();
			dto.setAmount(receipt.getAmount().toString());

			dto.setCustomerType(receipt.getCustomerType());
			dto.setCustomerId(receipt.getCustomerId());
			if (receipt.getCustomerType().equals("CUS")) {
				Customer customer = customerDaoImpl.getCustomerById(receipt.getCustomerId());
				dto.setCustomerCode(customer.getCode());
				if (customer.getAccountType().equals("C"))
					dto.setCustomerName(customer.getSurname());
				else
					dto.setCustomerName(customer.getDenotedByInitials().concat(" " + customer.getSurname()));
			} else if (receipt.getCustomerType().equals("ISU")) {
				Issuer issuer = issuerDaoImpl.getById(receipt.getCustomerId());
				dto.setCustomerCode(issuer.getCode());
				dto.setCustomerName(issuer.getName());
			}
			if (receipt.getDepositAccount() != null) {
				Fund fund = receipt.getFund();
				if (receipt.getDepositAccount().equals("N")) {
					dto.setFundid(fund.getId());
					dto.setFundAccount(configurationDaoImpl.getValueByPropName("accountNo"));
					dto.setFundBank(configurationDaoImpl.getValueByPropName("nameOfBank"));
					dto.setFundName(fund.getFundCode().concat(" - " + fund.getFundName()));
				} else {
					dto.setFundid(fund.getId());
					dto.setFundAccount(fund.getCdsAccount());
					dto.setFundBank(fund.getCustodian().getName());
					dto.setFundName(fund.getFundCode().concat(" - " + fund.getFundName()));
				}
			}

			dto.setId(receipt.getId());
			dto.setInstruction(receipt.getInstruction());
			dto.setPaymentType(receipt.getPaymentType());
			dto.setPurpose(receipt.getPurpose());
			dto.setReceiptNo(receipt.getReceiptNo());
			dto.setReqUserId(receipt.getReqUserId());
			dto.setStatus(receipt.getStatus());

			receiptDtos.add(dto);
		}
		return receiptDtos;
	}

	public void reject(int receiptid, ReceiptDto receiptDto) {
		Receipt receipt = daoImpl.getReceiptById(receiptid);
		if (receipt != null) {
			receipt.setStatus((byte) 3);
			receipt.setConfDate(new Date());
			receipt.setPurpose(receiptDto.getPurpose());
			receipt.setConfUserId(LoginAction.getCurrentLogingUser().getId());
			if (receipt.getPaymentType().equals("C")) {
				receipt.setInstruction(receiptDto.getInstruction());
				receipt.setChequeBank(receiptDto.getChequeBank());
				try {
					receipt.setChequeDate(format.parse(receiptDto.getChequeDate()));
				} catch (ParseException e) {
					e.printStackTrace();
				}
				receipt.setChequeNo(receiptDto.getChequeNo());
			} else {
				BankAccountDto accountDto = commenPayementModel.getBankAccount(receipt.getCustomerId(), receipt.getCustomerType(), receiptDto.getBankId());
				if (accountDto != null) {
					receipt.setBankAccount(accountDto.getAccountNo());
					receipt.setBankName(accountDto.getNameOfBank());
					receipt.setBankId(receiptDto.getBankId());
				}
			}
			daoImpl.rejectreceipt(receipt, null);
		}
	}

	public void cancelConfirmReceipt(int receiptid, ReceiptDto receiptDto) {
		Receipt receipt = daoImpl.getReceiptById(receiptid);
		if (receipt != null) {
			receipt.setStatus((byte) 2);
			MoneyTransactionModel model = new MoneyTransactionModel();
			List<MoneyTransaction> moneyTransactions = model.getReceiptReversTranasactions(receipt);
			daoImpl.rejectreceipt(receipt, moneyTransactions);
		}
	}
}
